//
//  ViewController.m
//  runtime
//
//  Created by yang on 2018/1/8.
//  Copyright © 2018年 YYY. All rights reserved.
//

#import "ViewController.h"

#import <objc/runtime.h>

#import <objc/message.h>

#import "NSObject+Runtime.h"

#import "UIImage+Category.h"

#import "Person.h"

#import "Teacher.h"

#import "Movie.h"

@interface ViewController () <UITableViewDelegate, UITableViewDataSource>

@property(nonatomic,strong)UIImageView *tempImageView1;

@property(nonatomic,strong)UIImageView *tempImageView2;

@property(nonatomic,strong)UITableView *tempTableView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
    int a = 9;
    int b = 11;
    NSLog(@"交换前：a = %d --- b = %d",a,b);
    
    //通过异或实现两个整数的交换
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    NSLog(@"交换后：a = %d --- b = %d",a,b);
    
    Person *p = [Person new];
    
    //1：通过runtime，实现方法交换
    Method m1 = class_getClassMethod([Person class], @selector(run));
    Method m2 = class_getClassMethod([Person class], @selector(study));
    method_exchangeImplementations(m1, m2);
    
    //交换两个类方法
    [Person run];
    [Person study];

    Method m3 = class_getInstanceMethod([p class], @selector(eat));
    Method m4 = class_getInstanceMethod([p class], @selector(sheep));
    method_exchangeImplementations(m3, m4);
    //交换两个实例方法
    [p eat];
    [p sheep];
    
    [self.view addSubview:self.tempImageView1];
    self.tempImageView1.image = [UIImage imageWithName:@"category"];
    
    [self.view addSubview:self.tempImageView2];
    self.tempImageView2.image = [UIImage imageNamed:@"category"];
    
    //2：通过runtime，在分类中设置属性
    p.name = @"战狼2";
    NSLog(@"姓名：%@",p.name);
    
    //3：通过runtime，获取类的属性列表
    NSLog(@"获取类的属性列表：%@", [Person propertiesList]);
    
    //4：通过runtime，获取类的方法列表
    NSLog(@"获取类的方法列表：%@", [Person methodsList]);
    
    //5：通过runtime，类的成员变量列表
    NSLog(@"获取类的成员变量列表：%@", [Person ivarsList]);
    
    //6：通过runtime，类的协议列表
    NSLog(@"获取类的协议列表：%@", [Person protocolList]);
    
    
    //7：通过runtime，调用对象方法，让对象发送消息
    //调用对象方法
    [p eat];
    //本质：让对象发送消息
    objc_msgSend(p, @selector(eat));
    
    // 用类名调用类方法，底层会自动把类名转换成类对象调用
    // 本质：让类对象发送消息
    //objc_msgSend([Person new], @selector(eat));
    
    //8：通过runtime，动态添加方法
    [p performSelector:@selector(eat)];
    
    
    //9：通过runtime，实现NSCoding的自动归档和解档
    [self encodeAndDecoder];
    
    //10：通过runtime，实现字典转模型的自动转换
    [self dictConvertModel];
    
    //11：通过runtime，动态修改变量的值
    [self dynamicModifyValue];
    /*
     [self.view addSubview:self.tempTableView];
     [self.tempTableView registerClass:[UITableViewCell self] forCellReuseIdentifier:@"identify"];
     */
}
//9：通过runtime，实现NSCoding的自动归档和解档
- (void)encodeAndDecoder
{
    Teacher *teacher = [[Teacher alloc] init];
    teacher.title = @"English Teacher";
    teacher.course = @"English";
    teacher.age = 60;
    teacher.address = @"北京市朝阳区";
    teacher.wage = 8000;
    
    NSString *documentPath  = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"userInfo"];
    //模型写入文件
    [NSKeyedArchiver archiveRootObject:teacher toFile:filePath];
    
    //读取
    Teacher *myTeacher = [NSKeyedUnarchiver unarchiveObjectWithFile: filePath];
    NSLog(@"%@", myTeacher);
}
//10：通过runtime，实现字典转模型的自动转换
- (void)dictConvertModel
{
    NSDictionary *user1 = @{ @"name":@"范冰冰",
                             @"age": @(32),
                             @"sex": @"Woman",
                             @"id": @"1111"
                             };
    NSDictionary *user2 = @{ @"name":@"林心如",
                             @"age": @(40),
                             @"sex": @"Woman",
                             @"id": @"2222"
                             };
    NSDictionary *user3 = @{ @"name":@"Lina",
                             @"age": @(20),
                             @"sex": @"Miss",
                             @"id": @"3333"
                             };
    
    NSDictionary *dict1 = @{ @"movieId":@"1001",
                             @"movieName": @"芳华",
                             @"pic_url": @"http://img4.imgtn.bdimg.com/it/u=1742626185,2547278809&fm=27&gp=0.jpg",
                             @"user" : user1
                             };
    NSDictionary *dict2 = @{ @"movieId":@"1002",
                             @"movieName": @"唐人街探案",
                             @"pic_url": @"http://img4.imgtn.bdimg.com/it/u=1742626185,2547278809&fm=27&gp=0.jpg",
                             @"user" : user2
                             };
    NSDictionary *dict3 = @{ @"movieId":@"1003",
                             @"movieName": @"摔跤吧爸爸",
                             @"pic_url": @"http://img2.imgtn.bdimg.com/it/u=2936881590,490535990&fm=27&gp=0.jpg",
                             @"user" : user3
                             };
    
    NSMutableArray *tempArray = [NSMutableArray array];
    NSArray *addarr = @[dict1 ,dict2, dict3];
    for (NSDictionary *item in addarr)
    {
        Movie *movie = [Movie objectWithDict:item];
        [tempArray addObject:movie];
    }
    
    Movie *movie1 = tempArray[0];
    NSLog(@"%@ %@ %@ %@", movie1.movieId, movie1.movieName, movie1.pic_url, movie1.user.id);
    Movie *movie2 = tempArray[1];
    NSLog(@"%@ %@ %@ %@", movie2.movieId, movie2.movieName, movie2.pic_url, movie2.user.id);
    Movie *movie3 = tempArray[2];
    NSLog(@"%@ %@ %@ %@", movie3.movieId, movie3.movieName, movie3.pic_url, movie3.user.id);
}

//11：通过runtime，动态修改变量的值
- (void)dynamicModifyValue
{
    Teacher *teacher = [Teacher new];
    teacher.address = @"东北省哈尔滨市";
    unsigned int count = 0;
    Ivar *ivar = class_copyIvarList([teacher class], &count);
    for (int i = 0; i<count; i++)
    {
        Ivar var = ivar[i];
        const char *varName = ivar_getName(var);
        NSString *proname = [NSString stringWithUTF8String:varName];
        if ([proname isEqualToString:@"_address"])
        {
            //给属性加下划线
            object_setIvar(teacher, var, @"河南省郑州市");
            break;
        }
    }
}
- (UIImageView *)tempImageView1
{
    if (!_tempImageView1)
    {
        _tempImageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(20, 70, 100, 100)];
    }
    return _tempImageView1;
}

- (UIImageView *)tempImageView2
{
    if (!_tempImageView2)
    {
        _tempImageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(20, 200, 100, 100)];
    }
    return _tempImageView2;
}

- (UITableView *)tempTableView
{
    if (!_tempTableView)
    {
        _tempTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 300, self.view.frame.size.width, 300)];
        _tempTableView.dataSource = self;
        _tempTableView.delegate = self;
    }
    return _tempTableView;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 10;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identify = @"identify";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identify forIndexPath:indexPath];
    if (!cell)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identify];
    }
    cell.textLabel.text = @"Hello World";
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
    UITableViewCell *cell2 = objc_msgSend(tableView, @selector(cellForRowAtIndexPath:), indexPath);
    
}
@end
